<template>
  <div class="app-container ai-chat">
    <div class="chat-container">
      <!-- 顶部标题 -->
      <div class="chat-header">
        <h2>AI 助手</h2>
        <p>与智能AI助手进行对话</p>
      </div>

      <!-- 聊天记录显示区域 -->
      <div class="chat-history" ref="chatHistory">
        <div
            v-for="(message, index) in messages"
            :key="index"
            :class="['message', message.role === 'user' ? 'user-message' : 'ai-message']"
        >
          <div class="message-content">
            <div class="avatar">
              <i :class="message.role === 'user' ? 'el-icon-user' : 'el-icon-robot'"></i>
            </div>
            <div class="text">
              <!-- 显示思考过程 -->
              <div v-if="message.thinking" class="thinking-content">
                <strong>思考过程：</strong>
                <pre>{{ message.thinking }}</pre>
              </div>
              <!-- 显示回复内容 -->
              <p>{{ message.content || '思考中...' }}</p>
              <span class="timestamp">{{ message.timestamp }}</span>
            </div>
          </div>
        </div>
      </div>

      <!-- 消息输入区域 -->
      <div class="chat-input">
        <el-input
            v-model="inputMessage"
            type="textarea"
            :rows="3"
            placeholder="请输入您的问题..."
            class="message-input"
            :disabled="loading"
            @keydown.enter.prevent="handleKeyDown"
        ></el-input>
        <div class="input-actions">
          <el-button
              type="primary"
              @click="sendMessage"
              :disabled="!inputMessage.trim() || loading"
              class="send-button"
          >
            发送
          </el-button>
          <el-button @click="clearHistory" class="clear-button">
            清空记录
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup name="AIChat">
import {ref, nextTick, onUnmounted} from 'vue'

// 响应式数据
const inputMessage = ref('')
const chatHistory = ref(null)
const loading = ref(false)
const currentStreamController = ref(null)

const messages = ref([
  {
    role: 'ai',
    content: '您好！我是小团团，有什么我可以帮您的吗？',
    timestamp: new Date().toLocaleTimeString()
  }
])

// 解析AI响应内容，分离思考过程和回复内容
function parseAIResponse(content) {
  const thinkMatch = content.match(/<think>([\s\S]*)<\/think>/);
  if (thinkMatch) {
    const thinking = thinkMatch[1].trim();
    const reply = content.replace(/<think>[\s\S]*<\/think>/, '').trim();
    return {thinking, reply};
  }
  return {thinking: '', reply: content};
}

// 发送消息
async function sendMessage() {
  if (!inputMessage.value.trim() || loading.value) return

  // 添加用户消息
  const userMessage = {
    role: 'user',
    content: inputMessage.value,
    timestamp: new Date().toLocaleTimeString()
  }
  messages.value.push(userMessage)

  // 添加初始AI消息，内容为空，显示"思考中..."
  const aiMessage = {
    role: 'ai',
    content: '',
    thinking: '',
    timestamp: new Date().toLocaleTimeString()
  }
  messages.value.push(aiMessage)

  // 清空输入框
  const messageToSend = inputMessage.value
  inputMessage.value = ''

  // 显示加载状态
  loading.value = true

  // 滚动到最新消息
  scrollToBottom()

  try {
    // 创建一个AbortController用于取消请求
    const controller = new AbortController()
    currentStreamController.value = controller

    // 使用 fetch API 调用 AI 聊天接口
    const response = await fetch(import.meta.env.VITE_APP_BASE_API + '/api/ai/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({prompt: messageToSend}),
      signal: controller.signal
    })

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    // 检查响应是否支持流式传输
    const reader = response.body?.getReader()
    if (!reader) {
      // 如果不支持流式传输，回退到原来的处理方式
      const data = await response.json()
      const {thinking, reply} = parseAIResponse(data.data || '抱歉，我没有理解您的问题，请您再解释得清楚一些。');
      messages.value[messages.value.length - 1] = {
        role: 'ai',
        content: reply,
        thinking: thinking,
        timestamp: new Date().toLocaleTimeString()
      }
      return
    }

    // 读取流数据
    const decoder = new TextDecoder()
    let accumulatedContent = '';

    while (true) {
      const {done, value} = await reader.read()
      if (done) break

      // 解码数据并更新消息内容
      const chunk = decoder.decode(value, {stream: true})
      accumulatedContent += chunk

      // 解析累积内容，分离思考过程和回复内容
      const {thinking, reply} = parseAIResponse(accumulatedContent);

      // 更新最后一条消息
      messages.value[messages.value.length - 1] = {
        role: 'ai',
        content: reply,
        thinking: thinking,
        timestamp: new Date().toLocaleTimeString()
      }

      // 滚动到最新消息
      scrollToBottom()
    }
  } catch (error) {
    // 错误处理
    if (error.name !== 'AbortError') {
      messages.value[messages.value.length - 1] = {
        role: 'ai',
        content: '抱歉，小团团暂时无法回应，请稍后再试。',
        timestamp: new Date().toLocaleTimeString()
      }
      console.error('AI聊天接口调用失败:', error)
    }
  } finally {
    // 隐藏加载状态
    loading.value = false
    // 滚动到最新消息
    scrollToBottom()
  }
}

// 清空聊天记录
function clearHistory() {
  // 如果有正在进行的流传输，取消它
  if (currentStreamController.value) {
    currentStreamController.value.abort()
    currentStreamController.value = null
  }

  messages.value = [
    {
      role: 'ai',
      content: '您好！我是AI助手，有什么我可以帮您的吗？',
      timestamp: new Date().toLocaleTimeString()
    }
  ]
  loading.value = false
}

// 处理键盘事件
function handleKeyDown(e) {
  if (e.altKey) {
    // Alt+Enter 插入换行
    const start = e.target.selectionStart;
    const end = e.target.selectionEnd;
    inputMessage.value = inputMessage.value.substring(0, start) + '\n' + inputMessage.value.substring(end);
    // 调整光标位置
    nextTick(() => {
      e.target.selectionStart = e.target.selectionEnd = start + 1;
    });
  } else {
    // Enter 发送消息
    sendMessage();
  }
}

// 滚动到底部
function scrollToBottom() {
  nextTick(() => {
    if (chatHistory.value) {
      chatHistory.value.scrollTop = chatHistory.value.scrollHeight
    }
  })
}

// 组件卸载时取消可能正在进行的流传输
onUnmounted(() => {
  if (currentStreamController.value) {
    currentStreamController.value.abort()
  }
})
</script>

<style scoped lang="scss">
.ai-chat {
  height: calc(100vh - 84px);
  padding: 20px;

  .chat-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    max-width: 1200px;
    margin: 0 auto;
    border: 1px solid #ebeef5;
    border-radius: 8px;
    background-color: #fff;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);

    .chat-header {
      padding: 20px;
      border-bottom: 1px solid #ebeef5;
      text-align: center;

      h2 {
        margin: 0 0 10px;
        font-size: 24px;
        color: #303133;
      }

      p {
        margin: 0;
        color: #909399;
      }
    }

    .chat-history {
      flex: 1;
      padding: 20px;
      overflow-y: auto;
      display: flex;
      flex-direction: column;

      .message {
        margin-bottom: 20px;
        max-width: 80%;

        .message-content {
          display: flex;

          .avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 15px;
            flex-shrink: 0;

            i {
              font-size: 20px;
            }
          }

          .text {
            flex: 1;

            .thinking-content {
              margin-bottom: 10px;
              padding: 10px;
              border-radius: 8px;
              background-color: #fffbe6;
              border: 1px solid #ffe58f;

              strong {
                display: block;
                margin-bottom: 5px;
                color: #faad14;
              }

              pre {
                margin: 0;
                white-space: pre-wrap;
                word-wrap: break-word;
                font-family: inherit;
              }
            }

            p {
              margin: 0 0 5px;
              padding: 10px;
              border-radius: 8px;
              line-height: 1.5;
              white-space: pre-wrap;
              min-height: 20px;
            }

            .timestamp {
              font-size: 12px;
              color: #909399;
              display: block;
              text-align: right;
              margin-top: 5px;
            }
          }
        }

        &.ai-message {
          align-self: flex-start;
          .message-content {
            .avatar {
              background-color: #67c23a;
            }

            .text {
              .thinking-content {
                background-color: #fffbe6;
                border: 1px solid #ffe58f;
              }

              p {
                background-color: #e6f7ff;
                border: 1px solid #d9edff;
              }
            }
          }
        }

        &.user-message {
          align-self: flex-end;
          .message-content {
            flex-direction: row-reverse;

            .avatar {
              background-color: #409eff;
              margin-right: 0;
              margin-left: 15px;
            }

            .text {
              p {
                background-color: #f0f9eb;
                border: 1px solid #e1f3d8;
                color: #333;
              }

              .timestamp {
                text-align: left;
              }
            }
          }
        }
      }
    }

    .chat-input {
      padding: 20px;
      border-top: 1px solid #ebeef5;

      .message-input {
        margin-bottom: 15px;
      }

      .input-actions {
        display: flex;
        justify-content: flex-end;
        gap: 10px;

        .send-button {

        }

        .clear-button {

        }
      }
    }
  }
}
</style>
